package org.mch.comm.velocity;

import java.io.Serializable;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.mch.comm.exec.MsgException;

/**
 * 描述：
 * 
 * @author MCH；Date：2008-10-01；<BR/>
 * 
 */
public class MVelocityEngine implements Serializable {

	private static final long serialVersionUID = 1L;

	public final static String ResourceLoaderClass = "RLClass";

	public final static String ResourceLoaderFile = "RLFile";

	private String inputEncoding = "UTF-8";
	private String outputEncoding = "UTF-8";

	private VelocityEngine engine;

	public String ResourceLoaderTYPE;

	public MVelocityEngine() {
		this.ResourceLoaderTYPE = ResourceLoaderClass;
	}

	public MVelocityEngine(String ResourceLoaderTYPE) {
		this.ResourceLoaderTYPE = ResourceLoaderTYPE;
	}

	public MVelocityEngine(String inputEncoding, String outputEncoding) {
		this.inputEncoding = inputEncoding;
		this.outputEncoding = outputEncoding;
	}

	public String getTemplateStrEO(String vmPath, VelBeanData beanData) throws Exception {
		Map<String, Object> map = new HashMap<>();
		map.put("bean", beanData);
		VelocityContext context = new VelocityContext();
		context.put("eo", map);

		Template tl = getEngine().getTemplate(vmPath);

		StringWriter writer = new StringWriter();
		tl.merge(context, writer);

		return writer.toString();
	}

	public String getTemplateStr(String vmPath, Map<String, Object> map) throws Exception {
		VelocityContext context = new VelocityContext();
		context.put("map", map);

		Template tl = getEngine().getTemplate(vmPath);

		StringWriter writer = new StringWriter();
		tl.merge(context, writer);

		return writer.toString();
	}

	public String getTemplateStr(String vmPath, String encoding, Map<String, Object> map) throws Exception {
		VelocityContext context = new VelocityContext();
		context.put("map", map);

		Template tl = getEngine().getTemplate(vmPath, encoding);

		StringWriter writer = new StringWriter();
		tl.merge(context, writer);

		return writer.toString();
	}

	public String getTemplateStr(String vmPath, VelocityContext context) throws Exception {

		Template tl = getEngine().getTemplate(vmPath);

		StringWriter writer = new StringWriter();
		tl.merge(context, writer);

		return writer.toString();
	}

	public String getTemplateStr(String vmPath, String encoding, VelocityContext context) throws Exception {

		Template tl = getEngine().getTemplate(vmPath, encoding);

		StringWriter writer = new StringWriter();
		tl.merge(context, writer);

		return writer.toString();
	}

	public VelocityEngine getEngine() throws Exception {
		if (engine == null) {
			engine = new VelocityEngine();
			Properties p = new Properties();

			if (ResourceLoaderFile.equals(getResourceLoaderTYPE())) {
				p.setProperty("resource.loader", "file");
				p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
			} else if (ResourceLoaderClass.equals(getResourceLoaderTYPE())) {
				p.setProperty("resource.loader", "class");
				p.setProperty("class.resource.loader.class",
						"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
			} else {
				throw new MsgException(getResourceLoaderTYPE());
			}

			p.setProperty("input.encoding", this.inputEncoding);
			p.setProperty("output.encoding", this.outputEncoding);

			engine.init(p);
		}
		return engine;
	}

	private static VelocityEngine defaultEngine;

	public static VelocityEngine getDefaultEngine(String resourceLoaderType, String inputEncoding, String outputEncoding)
			throws Exception {
		if (defaultEngine == null) {
			defaultEngine = new VelocityEngine();
			Properties p = new Properties();

			if (ResourceLoaderFile.equals(resourceLoaderType)) {
				p.setProperty("resource.loader", "file");
				p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
			} else if (ResourceLoaderClass.equals(resourceLoaderType)) {
				p.setProperty("resource.loader", "class");
				p.setProperty("class.resource.loader.class",
						"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
			} else {
				throw new MsgException(resourceLoaderType);
			}

			p.setProperty("input.encoding", inputEncoding);
			p.setProperty("output.encoding", outputEncoding);

			defaultEngine.init(p);
		}
		return defaultEngine;
	}

	public static VelocityEngine getDefaultEngine(String resourceLoaderType) throws Exception {
		if (defaultEngine == null) {
			defaultEngine = new VelocityEngine();
			Properties p = new Properties();

			if (ResourceLoaderFile.equals(resourceLoaderType)) {
				p.setProperty("resource.loader", "file");
				p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
			} else if (ResourceLoaderClass.equals(resourceLoaderType)) {
				p.setProperty("resource.loader", "class");
				p.setProperty("class.resource.loader.class",
						"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
			} else {
				throw new MsgException(resourceLoaderType);
			}

			p.setProperty("input.encoding", "GB18030");
			p.setProperty("output.encoding", "GB18030");

			defaultEngine.init(p);
		}
		return defaultEngine;
	}

	public String getResourceLoaderTYPE() {
		return ResourceLoaderTYPE;
	}

}
